package com.peiwan.user.service.impl;

import com.peiwan.user.dto.UserCreateDTO;
import com.peiwan.user.dto.UserDTO;
import com.peiwan.user.entity.User;
import com.peiwan.user.repository.UserRepository;
import com.peiwan.user.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {

    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDTO register(UserCreateDTO userCreateDTO) {
        logger.info("开始注册用户: {}", userCreateDTO.getUsername());
        
        try {
            // 检查用户名是否已存在
            if (existsByUsername(userCreateDTO.getUsername())) {
                logger.warn("用户名已存在: {}", userCreateDTO.getUsername());
                throw new RuntimeException("用户名已存在");
            }
            
            // 检查邮箱是否已存在
            if (userCreateDTO.getEmail() != null && existsByEmail(userCreateDTO.getEmail())) {
                logger.warn("邮箱已被使用: {}", userCreateDTO.getEmail());
                throw new RuntimeException("邮箱已被使用");
            }
            
            // 检查手机号是否已存在
            if (userCreateDTO.getPhone() != null && existsByPhone(userCreateDTO.getPhone())) {
                logger.warn("手机号已被使用: {}", userCreateDTO.getPhone());
                throw new RuntimeException("手机号已被使用");
            }
            
            // 创建新用户
            User user = new User();
            user.setUsername(userCreateDTO.getUsername());
            user.setPassword(passwordEncoder.encode(userCreateDTO.getPassword()));
            user.setPermission(userCreateDTO.getPermission() != null ? userCreateDTO.getPermission() : "user");
            user.setRole(userCreateDTO.getRole() != null ? userCreateDTO.getRole() : "陪陪");
            user.setNickname(userCreateDTO.getNickname());
            user.setAvatar(userCreateDTO.getAvatar());
            user.setPhone(userCreateDTO.getPhone());
            user.setEmail(userCreateDTO.getEmail());
            
            logger.info("保存用户信息: {}", user.getUsername());
            User savedUser = userRepository.save(user);
            logger.info("用户注册成功: {}", savedUser.getUsername());
            
            return convertToDTO(savedUser);
        } catch (Exception e) {
            logger.error("用户注册失败: {}", e.getMessage(), e);
            throw new RuntimeException("注册失败: " + e.getMessage());
        }
    }

    @Override
    public UserDTO login(String username, String password) {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new RuntimeException("密码错误");
        }
        
        return convertToDTO(user);
    }

    @Override
    public UserDTO getCurrentUser() {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        return convertToDTO(user);
    }

    @Override
    public UserDTO updateProfile(UserDTO userDTO) {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        // 更新允许修改的字段
        user.setNickname(userDTO.getNickname());
        user.setAvatar(userDTO.getAvatar());
        
        // 检查邮箱是否被其他用户使用
        if (userDTO.getEmail() != null && !userDTO.getEmail().equals(user.getEmail())) {
            if (existsByEmail(userDTO.getEmail())) {
                throw new RuntimeException("邮箱已被使用");
            }
            user.setEmail(userDTO.getEmail());
        }
        
        // 检查手机号是否被其他用户使用
        if (userDTO.getPhone() != null && !userDTO.getPhone().equals(user.getPhone())) {
            if (existsByPhone(userDTO.getPhone())) {
                throw new RuntimeException("手机号已被使用");
            }
            user.setPhone(userDTO.getPhone());
        }
        
        User updatedUser = userRepository.save(user);
        return convertToDTO(updatedUser);
    }

    @Override
    public List<UserDTO> getAllUsers() {
        // 检查权限
        String permission = SecurityContextHolder.getContext().getAuthentication()
                .getAuthorities().iterator().next().getAuthority();
        if (!"admin".equals(permission)) {
            throw new RuntimeException("无权访问");
        }
        
        return userRepository.findAll().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    @Override
    public UserDTO getUserByUsername(String username) {
        // 检查权限
        String permission = SecurityContextHolder.getContext().getAuthentication()
                .getAuthorities().iterator().next().getAuthority();
        if (!"admin".equals(permission)) {
            throw new RuntimeException("无权访问");
        }
        
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        return convertToDTO(user);
    }

    @Override
    public boolean existsByUsername(String username) {
        return userRepository.existsByUsername(username);
    }

    @Override
    public boolean existsByEmail(String email) {
        return userRepository.existsByEmail(email);
    }

    @Override
    public boolean existsByPhone(String phone) {
        return userRepository.existsByPhone(phone);
    }

    @Override
    public void deleteUser(String username) {
        // 检查权限
        String permission = SecurityContextHolder.getContext().getAuthentication()
                .getAuthorities().iterator().next().getAuthority();
        if (!"admin".equals(permission)) {
            throw new RuntimeException("无权访问");
        }
        
        if (!existsByUsername(username)) {
            throw new RuntimeException("用户不存在");
        }
        
        userRepository.deleteById(username);
    }

    @Override
    public void updateUserPermission(String username, String permission) {
        // 检查权限
        String currentPermission = SecurityContextHolder.getContext().getAuthentication()
                .getAuthorities().iterator().next().getAuthority();
        if (!"admin".equals(currentPermission)) {
            throw new RuntimeException("无权访问");
        }
        
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        if (!"admin".equals(permission) && !"user".equals(permission)) {
            throw new RuntimeException("无效的权限值");
        }
        
        user.setPermission(permission);
        userRepository.save(user);
    }

    @Override
    public String getUserPermission(String username) {
        // 检查权限
        String permission = SecurityContextHolder.getContext().getAuthentication()
                .getAuthorities().iterator().next().getAuthority();
        if (!"admin".equals(permission)) {
            throw new RuntimeException("无权访问");
        }
        
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        return user.getPermission();
    }

    @Override
    public boolean hasPermission(String username, String permission) {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        return permission.equals(user.getPermission());
    }

    @Override
    public UserDTO updateUser(String username, UserDTO userDTO) {
        logger.info("开始更新用户信息 - 用户名: {}", username);
        
        // 获取当前登录用户
        String currentUsername = SecurityContextHolder.getContext().getAuthentication().getName();
        String currentPermission = SecurityContextHolder.getContext().getAuthentication()
                .getAuthorities().iterator().next().getAuthority();
        logger.info("当前登录用户: {}, 权限: {}", currentUsername, currentPermission);
        
        // 如果不是管理员，只能更新自己的信息
        if (!"admin".equals(currentPermission) && !currentUsername.equals(username)) {
            logger.warn("权限不足 - 当前用户: {}, 目标用户: {}, 权限: {}", 
                currentUsername, username, currentPermission);
            throw new RuntimeException("无权访问");
        }

        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> {
                    logger.error("用户不存在 - 用户名: {}", username);
                    return new RuntimeException("用户不存在");
                });

        // 只更新非空字段
        if (userDTO.getRole() != null) {
            // 只有管理员可以修改角色
            if (!"admin".equals(currentPermission)) {
                logger.warn("无权修改角色 - 当前用户: {}, 权限: {}", currentUsername, currentPermission);
                throw new RuntimeException("无权修改角色");
            }
            user.setRole(userDTO.getRole());
        }
        if (userDTO.getNickname() != null) {
            user.setNickname(userDTO.getNickname());
        }
        if (userDTO.getPhone() != null) {
            user.setPhone(userDTO.getPhone());
        }
        if (userDTO.getEmail() != null) {
            user.setEmail(userDTO.getEmail());
        }
        if (userDTO.getPermission() != null) {
            // 只有管理员可以修改权限
            if (!"admin".equals(currentPermission)) {
                logger.warn("无权修改权限 - 当前用户: {}, 权限: {}", currentUsername, currentPermission);
                throw new RuntimeException("无权修改权限");
            }
            user.setPermission(userDTO.getPermission());
        }
        if (userDTO.getPassword() != null && !userDTO.getPassword().isEmpty()) {
            logger.info("更新密码 - 用户名: {}", username);
            user.setPassword(passwordEncoder.encode(userDTO.getPassword()));
        }

        User updatedUser = userRepository.save(user);
        logger.info("用户信息更新成功 - 用户名: {}", username);
        return convertToDTO(updatedUser);
    }

    private UserDTO convertToDTO(User user) {
        UserDTO userDTO = new UserDTO();
        userDTO.setUsername(user.getUsername());
        userDTO.setPermission(user.getPermission());
        userDTO.setRole(user.getRole());
        userDTO.setNickname(user.getNickname());
        userDTO.setAvatar(user.getAvatar());
        userDTO.setPhone(user.getPhone());
        userDTO.setEmail(user.getEmail());
        return userDTO;
    }
}